package com.annotation.config;

import com.annotation.aop.Calculator;
import com.annotation.aop.LogCalculator;
import com.annotation.entities.Blue;
import com.annotation.entities.Car;
import com.annotation.entities.Cat;
import com.annotation.entities.Color;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.*;

/**【主要研究目标:为容器中注册了什么组建，组建什么时候工作，功能是什么】
 *  1、@EnableAspectJAutoProxy是什么
 *      @Import(AspectJAutoProxyRegistrar.class)为容器导入AspectJAutoProxyRegistrar，
 *              再利用AspectJAutoProxyRegistrar为容器中注册组建
 *              internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator
 *              为容器中注册一个AnnotationAwareAspectJAutoProxyCreator（注解模式的aspectJ自动代理创建器）
 *  2、AnnotationAwareAspectJAutoProxyCreator
 *          ->AspectJAwareAdvisorAutoProxyCreator
 *              ->AbstractAdvisorAutoProxyCreator
 *                  ->AbstractAutoProxyCreator
 *                      ->implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
 *                          (使用bean的后处理接口，在bean初始化前后做事情，)、自动装配BeanFactory
 *     AbstractAutoProxyCreator.setBeanFactory()
 *     AbstractAutoProxyCreator.postProcessBeforeInstantiation()
 *
 *     AbstractAdvisorAutoProxyCreator.setBeanFactory()  .initBeanFactory
 *
 *     AspectJAwareAdvisorAutoProxyCreator .initBeanFactory()
 *
 *     流程：
 *          1、传入配置类创建IOC容器
 *          2、注册配置类，调用refresh()刷新容器
 *          3、初始化容器
 *          4、registerBeanPostProcessors()拦截bean的创建
 *              1）利用beanFactory.getBeanNamesForType(BeanPostProcessor.class,...获取所有容器中已经定义了的BeanPostProcessor
 *              2）给容器中添加一些BeabPostProcessor
 *              // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
 * 		        // Ordered, and the rest.
 * 		        3)、//First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
 * 		            优先注册实现了 PriorityOrdered 接口的BeanPostProcessor（PriorityOrdered继承了Ordered接口）
 * 		        4）、// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
 * 		            接下来注册实现了Ordered接口的BeanPostProcessor
 * 		        5）、// Finally, invoke all other BeanFactoryPostProcessors.
 * 		            最后注册一般的BeanPostProcessor（没有实现优先级接口的BeanPostProcessor）
 *              6）、创建BeanPostProcessor对象保存到容器中
 *                   创建org.springframework.aop.config.internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
 *                   1）、invokeAwareMethods():处理Aware接口的回调
 *                   2）、applyBeanPostProcessorBeforeInitialization()。应用后置处理器的beforeInitialization()
 *                          得到所有的beforeInitialization()方法，调用
 *                   3）、invokeInitMethods():执行自定义的初始化方法
 *                   4）、applyBeanPostProcessorsAfterInitialization()，执行后处理器的afterInitialization方法
 *                   5)、BeanPostProcessor（AnnotationAwareAspectJAutoProxyCreator）创建成功
 *              7）、把BeanPostProcessor注册到容器中，
 *                   调用beanFactory.addBeanPostProcessor();
 *  ------------------以上为创建AnnotationAwareAspectJAutoProxyCreator的过程-------------------
 *
 *    AnnotationAwareAspectJAutoProxyCreator-> postProcessBeforeInstantiation()【也是实现了BeanPostProcessor的后处理器】
 *        5、finishBeanFactoryInitialization(),完成beanFactory的初始化工作，创建剩下的单利bean实例
 *           1）、获取beanFactory中所有的bean的name，一次创建bean的对象
 */
@Import(Blue.class)
@EnableAspectJAutoProxy
@Configurable
public class MainConfigAop {

    @Bean
    @Lazy
    @DependsOn(value = "cat")
    public Color color(){
        return new Color();
    }

    @Bean
    @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Cat cat(){
        return new Cat();
    }

    @Bean
    public Car car(){
        return new Car();
    }

    @Bean
    public Calculator calculator(){
        return new Calculator();
    }

    @Bean
    public LogCalculator logCalculator(){
        return new LogCalculator();
    }

}
